#include <stdio.h>             // 标准输入输出库
#include <string.h>             // 标准输入输出库
#include "sdkconfig.h"         // ESP32 SDK配置头文件
#include "freertos/FreeRTOS.h" // FreeRTOS操作系统头文件
#include "freertos/task.h"     // FreeRTOS任务相关头文件
#include "freertos/ringbuf.h"
#include "esp_log.h"            // ESP32日志功能头文件
#include "usbd_core.h"          // USB设备核心库头文件
#include "usbd_cdc.h"           // USB CDC类头文件
#include "usbd_msc.h"           // USB MSC类头文件
#include "logic_analyzer_cdc.h" // 逻辑分析仪CDC头文件
#include "usb_public.h"         // 逻辑分析仪CDC头文件



#define USBD_VID           0xFFFF // USB厂商ID
#define USBD_PID           0xFFFF // USB产品ID
#define USBD_MAX_POWER     100    // USB最大功耗（单位：mA）
#define USBD_LANGID_STRING 1033   // USB语言ID（英语）

/*!< 配置描述符大小 */
#define LOGIC_USB_CONFIG_SIZE (9 + CDC_ACM_DESCRIPTOR_LEN) // USB配置描述符总大小

#ifdef CONFIG_USB_HS    // 如果配置为高速USB
#define CDC_MAX_MPS 512 // CDC最大包大小为512字节
#else
#define CDC_MAX_MPS 64 // 否则CDC最大包大小为64字节
#endif

#define LOGIC_READ_RB_SIZE (512) // 逻辑分析仪CDC读环形缓冲区大小

static const uint8_t logic_device_descriptor[] = {
    USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
};
static const uint8_t logic_config_descriptor[] = {
    USB_CONFIG_DESCRIPTOR_INIT(LOGIC_USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), // 配置描述符初始化
    CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02), // CDC ACM描述符初始化
};
char *logic_string_descriptors[] = {
    (char[]){ 0x09, 0x04 },             /* Langid */
    "MiDuo",                            /* Manufacturer */
    "Md-Link Logic Analyzer",           /* Product */
    "00000000000000000123456789ABCDFF", /* Serial Number */
};
static const uint8_t logic_device_quality_descriptor[] = {
    USB_DEVICE_QUALIFIER_DESCRIPTOR_INIT(USB_2_1, 0x00, 0x00, 0x00, 0x01),
};

static uint8_t *logic_device_descriptor_callback(uint8_t speed)
{
    (void)speed;
    return (uint8_t *)logic_device_descriptor;
}

static const uint8_t *logic_config_descriptor_callback(uint8_t speed)
{
    (void)speed;
    //ESP_EARLY_LOGI("MdLink", "call logic_config_descriptor");
    return logic_config_descriptor;
}
static const char *logic_string_descriptor_callback(uint8_t speed, uint8_t index)
{
    (void)speed;

    if (index >= (sizeof(logic_string_descriptors) / sizeof(char *))) {
        return NULL;
    }
    return logic_string_descriptors[index];
}

__WEAK const uint8_t *logic_device_quality_descriptor_callback(uint8_t speed)
{
    (void)speed;
    return logic_device_quality_descriptor;
}
// USB 描述符配置结构体
const struct usb_descriptor logic_descriptor = {
    // 设备描述符回调函数（获取设备的基本信息，如VID、PID、设备类等）
    .device_descriptor_callback = logic_device_descriptor_callback,
    // 配置描述符回调函数（定义USB设备的配置、接口、端点等）
    .config_descriptor_callback = logic_config_descriptor_callback,
    // 字符串描述符回调函数（返回厂商、产品、序列号等字符串信息）
    .string_descriptor_callback = logic_string_descriptor_callback,
    //.device_quality_descriptor_callback = logic_device_quality_descriptor_callback,

    // BOS（Binary Device Object Store）描述符（用于USB 2.1+，支持扩展能力描述）
    //.bos_descriptor = &bos_desc,
    // Microsoft OS 2.0描述符（用于Windows兼容性，如自动加载驱动）
    //.msosv2_descriptor = &msosv2_desc,

};

/////////////////////////////////////// usb ///////////////////////////////////////////////////////////////////////////////////
static char *TAG = "device_cdc_main";

//RingbufHandle_t logic_cdc_write_RB; // 逻辑分析仪CDC写环形缓冲区
RingbufHandle_t logic_cdc_read_RB=NULL;              // 逻辑分析仪CDC读环形缓冲
static uint8_t logic_read_buf_tmp[CDC_MAX_MPS]; // 非缓存RAM区的读缓冲区

// CDC ACM批量输出回调函数
static void la_usbd_cdc_acm_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
    // 将接收到的数据存入读环形缓冲区
    //ring_buffer_queue_arr(&cdc_read_ring_buffer, (char *)logic_read_buf_tmp, nbytes);
    xRingbufferSendFromISR(logic_cdc_read_RB, logic_read_buf_tmp, nbytes, NULL);
   // int res=xRingbufferSendFromISR(logic_cdc_read_RB, logic_read_buf_tmp, nbytes,NULL);
    //ESP_EARLY_LOGI(TAG, "logic command:%d, nbytes:%d , res:%d", logic_read_buf_tmp[0], nbytes, res);

    /* 启动下一次OUT端点读取传输 */
    usbd_ep_start_read(0, CDC_OUT_EP, logic_read_buf_tmp, sizeof(logic_read_buf_tmp));
}
extern SemaphoreHandle_t logic_write_SemBin;
// CDC ACM批量输入回调函数
static void la_usbd_cdc_acm_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
    //ESP_EARLY_LOGI(TAG, "logic analyzer bulk in, nbytes:%d", nbytes);
    // 如果传输的数据长度是最大包大小的整数倍且不为零，发送零长度包
    /* 释放互斥量: 开锁 */
    xSemaphoreGiveFromISR(logic_write_SemBin, NULL); //
    // if ((nbytes % CDC_MAX_MPS) == 0 && nbytes) {
    //     usbd_ep_start_write(0, CDC_IN_EP, NULL, 0);
    // }
}

// CDC OUT端点结构体定义
struct usbd_endpoint la_cdc_out_ep = {
    .ep_addr = CDC_OUT_EP,            // 端点地址
    .ep_cb = la_usbd_cdc_acm_bulk_out // 端点回调函数
};

// CDC IN端点结构体定义
struct usbd_endpoint la_cdc_in_ep = {
    .ep_addr = CDC_IN_EP,            // 端点地址
    .ep_cb = la_usbd_cdc_acm_bulk_in // 端点回调函数
};

struct usbd_interface la_intf0; // CDC接口0
struct usbd_interface la_intf1; // CDC接口1
// CDC ACM初始化函数
static void cdc_acm_init(uint8_t busid, uint32_t reg_base)
{
    usbd_desc_register(0, &logic_descriptor);

    /*!< cdc acm */
    usbd_add_interface(0, usbd_cdc_acm_init_intf(0, &la_intf0));
    usbd_add_interface(0, usbd_cdc_acm_init_intf(0, &la_intf1));
    usbd_add_endpoint(0, &la_cdc_out_ep);
    usbd_add_endpoint(0, &la_cdc_in_ep);
    extern void usbd_event_handler(uint8_t busid, uint8_t event);
    usbd_initialize(busid, reg_base, usbd_event_handler);
    if (logic_cdc_read_RB==NULL)
        // 创建输入环形缓冲区
        logic_cdc_read_RB = xRingbufferCreate(LOGIC_READ_RB_SIZE, RINGBUF_TYPE_NOSPLIT);


    // // 等待USB设备配置完成
    // while (!usb_device_is_configured())
    // {
    //     printf(".");
    //     vTaskDelay(100);
    // }
}

void logic_usbd_event_cfg(void)
{
    /*in usb config succeed, start first read*/
    usbd_ep_start_read(0, CDC_OUT_EP, logic_read_buf_tmp, sizeof(logic_read_buf_tmp));
}
// // CDC ACM数据发送函数（带DTR测试）
// static void la_cdc_acm_data_send_with_dtr_test(void)
// {
//     // if (ring_buffer_is_empty(&cdc_write_ring_buffer)) // 如果写环形缓冲区为空，直接返回
//     // {
//     //     return;
//     // }

//     // if (la_ep_tx_busy_flag == false) // 如果端点不忙
//     // {
//     //     la_ep_tx_busy_flag = true; // 设置发送忙标志
//     //     /*!< 发送数据 */
//     //     write_buffer_len = ring_buffer_num_items(&cdc_write_ring_buffer);                        // 获取缓冲区数据长度
//     //     ring_buffer_dequeue_arr(&cdc_write_ring_buffer, (char *)write_buffer, write_buffer_len); // 从缓冲区取出数据
//     //     usbd_ep_start_write(CDC_IN_EP, write_buffer, write_buffer_len);                          // 启动IN端点写入传输
//     //     write_buffer_len = 0;                                                                    // 重置缓冲区长度
//     //     while (la_ep_tx_busy_flag)                                                               // 等待发送完成
//     //     {
//     //         vTaskDelay(1);
//     //     }
//     // }
// }

// // 逻辑分析仪主任务函数
// static void logic_analyzer_main_task(void *pvParameter)
// {
//     // 初始化USB驱动和CDC接口

//     // ring_buffer_init(&cdc_write_ring_buffer); // 初始化写环形缓冲区
//     // ring_buffer_init(&cdc_read_ring_buffer);  // 初始化读环形缓冲区
//     ESP_LOGI(TAG, "usb cdc acm init done"); // 打印初始化完成日志

//     while (1) {
//         // 将接收到的数据发送回主机
//         la_cdc_acm_data_send_with_dtr_test();
//         vTaskDelay(pdMS_TO_TICKS(10)); // 延时10毫秒
//     }
// }

//static TaskHandle_t *xHandle_LA_CDC = NULL; // 逻辑分析仪CDC任务句柄

// 启动逻辑分析仪CDC功能
int logic_analyzer_cdc_start(void)
{
    cdc_acm_init(0, ESP_USBD_BASE); // 初始化CDC ACM

    // if (xHandle_LA_CDC != NULL) // 如果任务已存在，先删除
    // {
    //     vTaskDelete(xHandle_LA_CDC);
    // }
    // xTaskCreate(logic_analyzer_main_task, "LA_CDC task", 1024 * 4, NULL, 5, xHandle_LA_CDC); // 创建任务
    return 1;
}
// 停止逻辑分析仪CDC功能
int logic_analyzer_cdc_stop(void)
{
    // if (xHandle_LA_CDC != NULL) // 如果任务存在，删除任务
    // {
    //     vTaskDelete(xHandle_LA_CDC);
    // }
    usbd_deinitialize(0);         // 反初始化USB设备
    if(logic_cdc_read_RB)
    {
        vRingbufferDelete(logic_cdc_read_RB);
        logic_cdc_read_RB = NULL;
    }
    usb_esp_jtag_serial_enable(); // 启用JTAG串口
    return 1;
}

static uint8_t *logic_command_buf=NULL;

// 从CDC读取数据
void logic_analyzer_cdc_read(const uint8_t *data, uint32_t data_len)
{
    (void)data;
    if (data_len>1)
    {
        if (logic_command_buf)
        {
            memcpy(data, logic_command_buf + 1, data_len);
            vRingbufferReturnItem(logic_cdc_read_RB, (void *)logic_command_buf); // 释放读缓冲区空间
        }

        return;
    }
    size_t recv_len;
    uint8_t *buf;
    buf = xRingbufferReceive(logic_cdc_read_RB, &recv_len, portMAX_DELAY);
   // buf = xRingbufferReceive(logic_cdc_read_RB, &recv_len, pdMS_TO_TICKS(3000));
    if (recv_len>1)
    {
        logic_command_buf = buf;
    }else{
        //ESP_LOGI(TAG, "command:%d, recv_len:%d", buf[0] ,recv_len);
        /*环形缓冲区足够大，就直接释放了*/
        vRingbufferReturnItem(logic_cdc_read_RB, (void *)buf); // 释放读缓冲区空间
    }

    //ring_buffer_dequeue_arr(&cdc_read_ring_buffer, (char *)data, data_len); // 从读环形缓冲区取出数据
    *(uint8_t *)data = buf[0];
}

// 向CDC写入数据
void logic_analyzer_cdc_write(const uint8_t *data, uint32_t data_len)
{

    usbd_ep_start_write(0, CDC_IN_EP, data, data_len);
    
    //int res = usbd_ep_start_write(0, CDC_IN_EP, data, data_len);
    //ESP_LOGE(TAG, "send command:%c, data_len:%d, res:%d", data[0], data_len, res);
    // ring_buffer_queue_arr(&cdc_write_ring_buffer, (char *)data, data_len); // 将数据存入写环形缓冲区
}
